<template>
  <tm-sheet :margin="[0, 0]" :padding="[0, 0]">
    <view v-if="props.quickBtn.length > 0">
      <tm-text _class="py-24  px-16" color="grey" label="快捷方式"></tm-text>
      <view class="flex flex-row flex-row-top-start flex-wrap">
        <tm-tag
          :color="props.color"
          @click="quickChangeClick(item)"
          v-for="(item, index) in props.quickBtn"
          :key="index"
          text
          outlined
          :shadow="0"
          :label="item.label"
        ></tm-tag>
      </view>
    </view>
    <view class="flex flex-row flex-row-center-between mt-24 px-16 mb-32">
      <tm-text color="grey" label="自定时间范围"></tm-text>
      <tm-icon @click="clear" :font-size="24" color="grey" name="tmicon-delete"></tm-icon>
    </view>
    <view class="flex flex-row flex-row-center-center px-16">
      <tm-sheet
        text
        @click="changeFocus(0)"
        :round="24"
        class="flex-1"
        parenClass="flex-1"
        _class="flex flex-row flex-row-center-center"
        :color="focusIndex == 0 ? props.color : 'grey-4'"
        :height="76"
        outlined
        :border="4"
        :margin="[0, 0]"
        :padding="[32, 0]"
      >
        <view
          :userInteractionEnabled="false"
          style="width: 200rpx"
          class="flex flex-row flex-row-center-center"
        >
          <tm-text v-if="!valuedate_start_str" color="grey" label="开始时间"></tm-text>
          <tm-text
            v-if="valuedate_start_str"
            :color="focusIndex == 0 ? props.color : 'grey'"
            :label="valuedate_start_str"
          ></tm-text>
        </view>
      </tm-sheet>
      <view class="px-24">
        <tm-text :font-size="28" _class="text-weight-b" label="至"></tm-text>
      </view>
      <tm-sheet
        text
        @click="changeFocus(1)"
        :round="24"
        class="flex-1"
        parenClass="flex-1"
        _class="flex flex-row flex-row-center-center"
        :color="focusIndex == 1 ? props.color : 'grey-4'"
        :height="76"
        outlined
        :border="4"
        :margin="[0, 0]"
        :padding="[32, 0]"
      >
        <view
          :userInteractionEnabled="false"
          style="width: 200rpx"
          class="flex flex-row flex-row-center-center"
        >
          <tm-text v-if="!valuedate_end_str" color="grey" label="结束时间"></tm-text>
          <tm-text
            v-if="valuedate_end_str"
            :color="focusIndex == 1 ? props.color : 'grey'"
            :label="valuedate_end_str"
          ></tm-text>
        </view>
      </tm-sheet>
    </view>
    <view>
      <tm-time-view
        :showDetail="props.showDetail"
        :immediateChange="props.immediateChange"
        :start="starTtime"
        :end="endTtime"
        @change="timeChange"
        v-model="picker_focus_date"
        v-model:model-str="picker_focus_date_str"
        :defaultValue="picker_focus_date"
      ></tm-time-view>
    </view>
    <view v-if="props.showBtn">
      <tm-button
        :color="props.color"
        @click="confirm"
        :round="24"
        :shadow="3"
        block
        label="确认"
      ></tm-button>
    </view>
  </tm-sheet>
</template>

<script lang="ts" setup>
  import { ref, computed, nextTick, PropType, watch } from 'vue';
  import tmSheet from '@/tmui/components/tm-sheet/tm-sheet.vue';
  import tmTag from '@/tmui/components/tm-tag/tm-tag.vue';
  import tmText from '@/tmui/components/tm-text/tm-text.vue';
  import tmIcon from '@/tmui/components/tm-icon/tm-icon.vue';
  import tmButton from '@/tmui/components/tm-button/tm-button.vue';
  import tmTimeView from '@/tmui/components/tm-time-view/tm-time-view.vue';
  import * as dayjs from '../../tool/dayjs/esm/index';
  import { chownSync } from 'fs';
  const DayJs = dayjs.default;
  interface showDetail {
    year: boolean;
    month: boolean;
    day: boolean;
    hour: boolean;
    minute: boolean;
    second: boolean;
  }
  interface quickBtnType {
    label: string;
    fun?: () => [string | number | Date | dayjs.Dayjs, string];
    color?: 'primary';
    //这个是内部代号，如果提供了，上面的fun可以不用提供，且无效
    // br:本日，bz:本周,by:本月,jsy:近三个月,bn:本年,d7：近7天，d30:近30天
    type?: 'br' | 'bz' | 'by' | 'jsy' | 'bn' | 'd7' | 'd30';
  }
  const props = defineProps({
    color: {
      type: String,
      default: 'primary',
    },
    //需要展现的时间格式类型
    showDetail: {
      type: Object as PropType<showDetail>,
      default: () => {
        return {
          year: true,
          month: true,
          day: true,
          hour: false,
          minute: false,
          second: false,
        };
      },
    },
    //展示格式。最终影响到modelStr输出格式的内容。
    format: {
      type: String,
      default: 'YYYY-MM-DD',
    },
    immediateChange: {
      type: Boolean,
      default: false,
    },
    quickBtn: {
      type: Array as PropType<Array<quickBtnType>>,
      default: () => {
        return [
          {
            label: '本日',
            fun: null,
            color: 'primary',
            type: 'br',
          },
          {
            label: '本周',
            fun: null,
            color: 'primary',
            type: 'bz',
          },
          {
            label: '本月',
            fun: null,
            color: 'primary',
            type: 'by',
          },
          {
            label: '近三月',
            fun: null,
            color: 'primary',
            type: 'jsy',
          },
          {
            label: '本年',
            fun: null,
            color: 'primary',
            type: 'bn',
          },
          {
            label: '近7天',
            fun: null,
            color: 'primary',
            type: 'd7',
          },
          {
            label: '近30天',
            fun: null,
            color: 'primary',
            type: 'd30',
          },
        ];
      },
    },
    start: {
      type: [String, Number, Date],
      default: new Date().setFullYear(new Date().getFullYear() - 1),
    },
    end: {
      type: [String, Number, Date],
      default: new Date().setFullYear(new Date().getFullYear() + 1),
    },
    defaultValue: {
      type: Array as PropType<Array<String | Number | Date>>,
      default: () => [],
    },
    /**
     * 不受formart控制，始终完整显示，必须规范
     * */
    modelValue: {
      type: Array as PropType<Array<String | Number | Date>>,
      default: () => [],
    },
    /**
     * 只对外显示输出formart的格式字符串，可能不规范
     * */
    modelStr: {
      type: Array as PropType<Array<String>>,
      default: () => [],
    },
    /** 当改变日期时，是否需要同步到vmodel变量中，立即执行双向同步，如果为false日期的改变不会同步到vmodel中
     * 然后需要你自行调用refs.getNowDate()来获取或者触发同步数据
     * 这里设置的意义是：当你需要同步日期数据，由用户设置时，如果你设置了一个确认按钮来同步用户设置的日期，那么这里可以设置为fase，
     * 然后你自行添加 一个确认按钮来触发refs.getNowDate()来同步数据，以执行用户的确认时间，否则不会同步。
     */
    asyncModel: {
      type: Boolean,
      default: true,
    },
    showBtn: {
      type: Boolean,
      default: true,
    },
  });
  const emits = defineEmits(['change', 'update:modelValue', 'update:modelStr', 'confirm', 'clear']);
  const valuedate_start = ref('');
  const valuedate_end = ref('');
  const focusIndex = ref(-1);
  const picker_focus_date = ref('');
  const picker_focus_date_str = ref('');
  const defaultFormat = 'YYYY-MM-DD HH:mm:ss';
  let tid: any = NaN;
  /** 开始时间 */
  const starTtime = computed(() => DayJs(props.start).format(defaultFormat));
  /** 结束时间 */
  const endTtime = computed(() => DayJs(props.end).format(defaultFormat));

  watch(
    () => props.modelValue,
    () => {
      clearTimeout(tid);
      tid = setTimeout(() => {
        setDate(props.modelValue);
      }, 100);
    },
    { deep: true, immediate: true },
  );
  const valuedate_start_str = computed(() => {
    if (!valuedate_start.value) return '';
    return DayJs(valuedate_start.value).format(props.format);
  });

  const valuedate_end_str = computed(() => {
    if (!valuedate_end.value) return '';
    return DayJs(valuedate_end.value).format(props.format);
  });
  function changeFocus(index: number) {
    focusIndex.value = index;
    let vstd = valuedate_start.value;
    let vsed = valuedate_end.value;

    if (index == 0 && !valuedate_start.value) {
      vstd = DayJs(valuedate_end.value).isValid()
        ? valuedate_end.value
        : DayJs().format(defaultFormat);
    }
    if (index == 1 && !valuedate_end.value) {
      vsed = DayJs(valuedate_start.value).isValid()
        ? valuedate_start.value
        : DayJs().format(defaultFormat);
    }

    setDate([vstd, vsed]);
  }

  function timeChange(evt: string) {
    if (focusIndex.value == -1) focusIndex.value = 0;

    if (focusIndex.value == 0) {
      valuedate_start.value = picker_focus_date.value;
    } else if (focusIndex.value == 1) {
      valuedate_end.value = picker_focus_date.value;
    }

    // #ifdef APP-NVUE
    updateTime();
    // #endif

    // #ifndef APP-NVUE
    nextTick(() => {
      updateTime();
    });
    // #endif
  }
  function updateTime() {
    checkTimeVaild();
    if (props.asyncModel) {
      emits('update:modelValue', [valuedate_start.value, valuedate_end.value]);
      emits('update:modelStr', [
        DayJs(valuedate_start.value).format(props.format),
        DayJs(valuedate_end.value).format(props.format),
      ]);
    }
    nextTick(() => {
      emits('change', [valuedate_start.value, valuedate_end.value]);
    });
  }
  //检查两个时间的正确性,就是后者要大于前者.
  function checkTimeVaild() {
    if (valuedate_end.value.length == 0 || valuedate_start.value.length == 0) return;
    if (focusIndex.value == 0) {
      if (DayJs(valuedate_start.value).isAfter(valuedate_end.value, 'second')) {
        valuedate_end.value = valuedate_start.value;
      }
    }
    if (focusIndex.value == 1) {
      if (DayJs(valuedate_end.value).isBefore(valuedate_start.value, 'second')) {
        valuedate_start.value = valuedate_end.value;
      }
    }
  }

  function quickChangeClick(item: quickBtnType) {
    let dstr = [];
    let typesar = ['br', 'bz', 'by', 'jsy', 'bn', 'd7', 'd30'];
    if (typeof item?.type === 'string' && typesar.includes(item?.type)) {
      let str = item?.type ?? '';
      if (str == 'br') {
        dstr = [DayJs().format(), DayJs().format()];
      } else if (str == 'bz') {
        let dt = DayJs();
        dstr = [
          dt.startOf('week').subtract(1, 'day').format(),
          dt.endOf('week').subtract(1, 'day').format(),
        ];
      } else if (str == 'by') {
        let dt = DayJs();
        dstr = [dt.startOf('month').format(), dt.endOf('month').format()];
      } else if (str == 'jsy') {
        let dt = DayJs();
        dstr = [dt.startOf('month').subtract(2, 'month').format(), dt.endOf('month').format()];
      } else if (str == 'bn') {
        let dt = DayJs();
        dstr = [dt.startOf('year').format(), dt.endOf('year').format()];
      } else if (str == 'd7') {
        let dt = DayJs();
        dstr = [dt.subtract(6, 'day').format(), dt.format()];
      } else if (str == 'd30') {
        let dt = DayJs();
        dstr = [dt.subtract(29, 'day').format(), dt.format()];
      }
    } else {
      if (typeof item?.fun == 'function') {
        dstr = item.fun();
        if (typeof idstr == 'function') {
          dstr = dstr();
        }
      }
    }
    if (Array.isArray(dstr)) {
      if (dstr.length !== 2) return;

      valuedate_start.value = DayJs(dstr[0]).format(defaultFormat);
      valuedate_end.value = DayJs(dstr[1]).format(defaultFormat);
      if (focusIndex.value == -1) {
        focusIndex.value = 0;
      }
      if (focusIndex.value == 0) {
        picker_focus_date.value = valuedate_start.value;
      }
      if (focusIndex.value == 1) {
        picker_focus_date.value = valuedate_end.value;
      }
      // 加上  触发点击最近时间的更新
      if (props.asyncModel) {
        // #ifdef APP-NVUE
        updateTime();
        // #endif

        // #ifndef APP-NVUE
        nextTick(() => {
          updateTime();
        });
        // #endif
      }
    }
  }

  function setDate(ar: Array<String | Number | Date>) {
    if (Array.isArray(ar) && ar?.length == 2) {
      valuedate_start.value = DayJs(ar[0]).isValid()
        ? DayJs(ar[0]).format(defaultFormat)
        : DayJs(props.start).format(defaultFormat);
      valuedate_end.value = DayJs(ar[1]).isValid()
        ? DayJs(ar[1]).format(defaultFormat)
        : DayJs(props.end).format(defaultFormat);
      focusIndex.value = focusIndex.value == -1 ? 0 : focusIndex.value;
      if (!DayJs(ar[focusIndex.value]).isValid()) return;
      picker_focus_date.value = DayJs(ar[focusIndex.value]).format(defaultFormat);
    }
  }
  function confirm() {
    emits('update:modelValue', [valuedate_start.value, valuedate_end.value]);
    emits('update:modelStr', [
      valuedate_start.value && DayJs(valuedate_start.value).format(props.format),
      valuedate_end.value && DayJs(valuedate_end.value).format(props.format),
    ]);
    emits('confirm', [valuedate_start.value, valuedate_end.value]);
  }
  function getNowDate(): [string, string] {
    updateTime();
    return [valuedate_start.value, valuedate_end.value];
  }
  function clear() {
    valuedate_start.value = '';
    valuedate_end.value = '';
    emits('update:modelStr', ['', '']);
    emits('clear');
  }
  defineExpose({ getNowDate });
</script>

<style></style>
